#import "FlickrImport.h"
#import "PreferenceController.h"
#import "MEFlickrUser.h"
#import "MEFlickrPhoto.h"
#import "MEFlickrConnection.h"
#import "ImageTextCell.h"

// we put this to make compiler happier... not absolutely necessary
@interface OFFlickrInvocation (OurOwnInvocation)
- (void)flickr_photos_search:(id)userinfo text:(NSString*)searchText selector:(SEL)aSelector;
- (void) flickr_people_getInfo: (id) userInfo user_id: (NSString *) str selector: (SEL) aSelector;
@end

@implementation FlickrImport

+ (void) initialize {
    NSMutableDictionary *defaultValues = [NSMutableDictionary dictionary];
    
    [defaultValues setValue:@"" forKey:MEFlickrFrob];
    [defaultValues setValue:@"" forKey:MEFlickrToken];
    [[NSUserDefaults standardUserDefaults] registerDefaults:defaultValues];
    
    NSLog(@"registered user defaults: %@", defaultValues);
}

- (void) dealloc {
    [preferenceController release];
    
    [invoc release];
    [context release];
    [flickrUserList release];
    [flickrPhotoExif release];
    [flickrPhotoSet release];
    
    [super dealloc];
}

// UI Methods
- (void)awakeFromNib {
    MEFlickrConnection *conn = [MEFlickrConnection getConnectionWithDelegate:self];
    
    context = [[conn context] retain];
    invoc = [[conn invoc] retain];
    
    flickrUserList = [[NSMutableArray alloc] init];
    flickrPhotoSet = [[NSMutableArray alloc] init];
    flickrPhotoExif = [[NSMutableDictionary alloc] init];

	// set the new custom cell
	NSTableColumn* column = [[flickrUsers tableColumns] objectAtIndex:0];
	
	ImageTextCell* cell = [[[ImageTextCell alloc] init] autorelease];	
	[column setDataCell: cell];		
    
	BOOL useDelegateMethods = YES;
	
	if (useDelegateMethods) {
		// Variant 1: use delegate methods
		// inform the cell that this instance implements the delegate methods
		[cell setDataDelegate: self];	
		
	}     
    
    if([[self token] isEqualTo:@""]){
        [self showPreferences];
    }else{
        //setup user defaults
        [self updateUserDetails];
    }
}

- (NSImage*) iconForCell: (ImageTextCell*) cell data: (NSObject*) data {
	MEFlickrUser *user = (MEFlickrUser *) data;
    return [user buddyIcon];
}

- (NSString*) primaryTextForCell: (ImageTextCell*) cell data: (NSObject*) data {
	MEFlickrUser *user = (MEFlickrUser *) data;
	return [user primaryDescription];
}
- (NSString*) secondaryTextForCell: (ImageTextCell*) cell data: (NSObject*) data {
	MEFlickrUser *user = (MEFlickrUser *) data;
	return [user secondaryDescription];
}

- (void) updateUserDetails; {
    
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [invoc setUserInfo:@"getMyInfo"];
    [invoc callMethod:@"flickr.people.getInfo"
            arguments:[NSArray arrayWithObjects:@"user_id", 
                [defaults objectForKey:MEFlickrUserId] , nil]];

}


- (IBAction) showPreferencePanel: (id) sender; {
    [self showPreferences];
}

- (void) showPreferences {
    if(!preferenceController) {
        preferenceController = [[PreferenceController alloc] init];
    }
    
    [preferenceController showWindow:self]; 
    
}

- (NSString *) frob; {
    return [[NSUserDefaults standardUserDefaults] stringForKey:MEFlickrFrob];
}

- (NSString *) token; {
    return [[NSUserDefaults standardUserDefaults] stringForKey: MEFlickrToken];
}

- (int) numberOfRowsInTableView: (NSTableView *) aTableView; {
    if([aTableView isEqualTo: flickrUsers ]){
        return [flickrUserList count];
    }else{
        return [flickrPhotoSet count];
    }
}

- (id) tableView: (NSTableView *) aTableView
            objectValueForTableColumn: (NSTableColumn *) aTableColumn
             row: (int) row; {
    if([aTableView isEqualTo: flickrUsers ]){
       return [flickrUserList objectAtIndex: row];
    }else{
        return [[flickrPhotoSet objectAtIndex: row] title];
    }
}

- (void) tableViewSelectionDidChange : (NSNotification *) notification {
    if([[notification object] isEqualTo:flickrUsers]){
        int row = [flickrUsers selectedRow];
        NSLog(@"selected user %@ nsid %@",
              [[flickrUserList objectAtIndex: row] userName],
              [[flickrUserList objectAtIndex: row] nsId]);
        
        [flickrUserPhotos deselectAll:self];
        [flickrPhotoSet removeAllObjects];
        [flickrUserPhotos reloadData];
        [flickrPhoto setImage: [[NSImage alloc] initWithSize: NSMakeSize(200.0,200.0)]];
        
        //flickr.people.getPublicPhotos
        [invoc setUserInfo: @"getPublicPhotos"];
        [invoc callMethod:@"flickr.people.getPublicPhotos"
                arguments:[NSArray arrayWithObjects:@"user_id", 
                    [[flickrUserList objectAtIndex: row] nsId],
                    @"extras", @"original_format,o_dims",
                    nil]];        
    }else{
        [importToiPhoto setEnabled:YES];
        
        MEFlickrPhoto *tmp_photo =  [flickrPhotoSet objectAtIndex: [flickrUserPhotos selectedRow]];
        
        NSURL *tmp_url = [NSURL URLWithString:[context photoURLFromID: [tmp_photo photoId]
                                                             serverID: [tmp_photo server]
                                                               secret: [tmp_photo secret]
                                                                 size: nil
                                                                 type: nil ]];
        NSImage *tmp_icon = [[NSImage alloc] initWithContentsOfURL: tmp_url];
        
        [flickrPhoto setImage: tmp_icon];

        //Get the photo exif
        [invoc setUserInfo:@"getExif"];
        [invoc callMethod:@"flickr.photos.getExif"
                arguments:[NSArray arrayWithObjects:@"photo_id", [tmp_photo photoId], 
                    @"secret", [tmp_photo secret], nil]];        

    }
}


// Flickr Methods
- (void) getExif: (NSXMLDocument*)xmldoc; {
    NSDictionary *payload = [xmldoc flickrDictionaryFromDocument];

    NSString *photo_id = [payload valueForKeyPath:@"photo._id"];
    NSEnumerator *p_enum = [flickrPhotoSet objectEnumerator];
    MEFlickrPhoto *tmp_photo;
    
    while(tmp_photo = [p_enum nextObject]){
        if([[tmp_photo photoId] isEqualTo:photo_id]){
            NSLog(@"exif data:\n%@", [payload valueForKeyPath:@"photo.exif"]);
            [tmp_photo setExif: [payload valueForKeyPath:@"photo.exif"] ];
            break;
        }
    }
}


- (void) handleErrors: (id)caller errorCode:(int)error data:(id)data; {
        
    if(error == OFConnectionCanceled){
        return;
    }
    
    NSString *errMsg = [NSString stringWithFormat:@"[FlickrImport] Error: %@", data];
    
	[[NSAlert alertWithMessageText:errMsg
                     defaultButton:@"Go back"
                   alternateButton:nil
                       otherButton:nil
         informativeTextWithFormat:nil
        ] runModal];    
}


- (void)flickrInvocation:(OFFlickrInvocation*)invocation errorCode:(int)errcode errorInfo:(id)errinfo {
    NSString *userinfo = [invoc userInfo];

	if (errcode == OFConnectionCanceled) {
		NSLog(@"FlickrImport: canceled! state=%@", userinfo);
		return;
	}
	
	NSLog(@"FlickrImport: error! code=%d, errinfo=%@, state=%@", errcode, errinfo, userinfo);
    
	NSString *errmsg=[NSString stringWithFormat:@"%@ (error code %d)",
		((errcode < 0) ? @"Internal error" : @"Flickr API error"), errcode];    
    
    NSString *informText = nil;
    
	[[NSAlert alertWithMessageText:errmsg
                     defaultButton:@"Go back"
                   alternateButton:nil
                       otherButton:nil
         informativeTextWithFormat:informText
        ] runModal];	    
}

- (void)flickrInvocation:(OFFlickrInvocation*)invocation didFetchData:(NSXMLDocument*)xmldoc; {
    NSString *userInfo = [invoc userInfo];
    
   // NSLog(@"FlickrImport: going to invoke selector for: %@:", userInfo);
    
    SEL flickrSel = NSSelectorFromString([userInfo stringByAppendingString:@":"]);
    [self performSelector:flickrSel withObject:xmldoc];

}

// Invoke Flickr Requests

- (void) getList: (NSXMLDocument*)xmldoc; {
    NSDictionary *payload = [xmldoc flickrDictionaryFromDocument];
    //NSLog(@"payload %@", payload);
    
    NSArray *tmp = [payload valueForKeyPath: @"contacts.contact"];
    
    NSEnumerator *f_enum = [tmp objectEnumerator];
    NSDictionary *elem;
    
    while(elem = [f_enum nextObject]){
        [invoc setUserInfo: @"getPeopleInfo"];
        [invoc callMethod:@"flickr.people.getInfo"
                arguments:[NSArray arrayWithObjects:@"user_id", 
                    [elem valueForKey:@"_nsid"] , nil]];
    }
}

- (IBAction)importToiPhoto:(id)sender; {
    
    NSString *tmpDir = [self temporaryDirectory];
    
    NSIndexSet *rows = [flickrUserPhotos selectedRowIndexes];
    unsigned int currentIndex = [rows firstIndex];

    while(currentIndex != NSNotFound){
        MEFlickrPhoto *tmpPhoto = [flickrPhotoSet objectAtIndex: currentIndex ];        
        [tmpPhoto downloadPhotoTo: tmpDir];

        currentIndex = [rows indexGreaterThanIndex: currentIndex];
    }
}

- (void) getPublicPhotos: (NSXMLDocument*)xmldoc; {    
    NSDictionary *payload = [xmldoc flickrDictionaryFromDocument];
    
    //empty the photo set
    [flickrPhotoSet removeAllObjects];
    
    //update it with the dictionary
    NSEnumerator *p_enum = [[payload valueForKeyPath: @"photos.photo"] objectEnumerator];
    NSDictionary *elem;
    while(elem = [p_enum nextObject]){
        MEFlickrPhoto *tmp_photo = [[MEFlickrPhoto alloc] initWithDictionary: elem];
        [flickrPhotoSet addObject: tmp_photo];
    }
    
    [flickrUserPhotos reloadData];
}

- (void) getPeopleInfo: (NSXMLDocument*)xmldoc; {
    NSDictionary *payload = [xmldoc flickrDictionaryFromDocument];
    
    [flickrUserList addObject: [[MEFlickrUser alloc] initWithDictionary: [payload valueForKey:@"person"] ] ];
    [flickrUsers reloadData];    
}

- (void) getMyInfo: (NSXMLDocument *) xmldoc {
    NSDictionary *payload = [xmldoc flickrDictionaryFromDocument];
    
    //NSLog(@"payload %@", [payload valueForKeyPath:@"person.photos.count.$"]);

    [flickrUserList addObject: [[MEFlickrUser alloc] initWithDictionary: [payload valueForKey:@"person"] ] ];
    [flickrUsers reloadData];
    
    [invoc setUserInfo: @"getList"];
    [invoc callMethod:@"flickr.contacts.getPublicList"
            arguments:[NSArray arrayWithObjects:
                @"user_id", [payload valueForKeyPath:@"person._nsid"], 
                @"per_page", @"1000", nil]];
}


- (NSString *)temporaryDirectory {
    NSString *tempDir =[NSTemporaryDirectory()
        stringByAppendingPathComponent:
        [[NSProcessInfo processInfo] processName]];
    
    NSFileManager *fileManager = [NSFileManager defaultManager];
    
    // Create the parent folder
    if([fileManager fileExistsAtPath: tempDir] == NO){
        [fileManager createDirectoryAtPath:tempDir attributes:nil];
    }
    
    tempDir = [tempDir stringByAppendingPathComponent:NSUserName()];
    
    // delete and create the child folder
    if([fileManager fileExistsAtPath: tempDir] == NO){
        [fileManager createDirectoryAtPath:tempDir attributes:nil];
    }else{
        [fileManager removeFileAtPath: tempDir handler:nil];
        [fileManager createDirectoryAtPath:tempDir attributes:nil];
    }

    return tempDir;
}

@end
